package extensionTools.smvCreator;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Date;

import javax.xml.xpath.XPathExpressionException;

import exportedAPI.opcatAPI.ISystem;
import extensionTools.smvCreator.Exceptions.SmvCreatorException;
import extensionTools.smvCreator.Exceptions.SmvDBException;
import extensionTools.smvCreator.Exceptions.XmlParserException;

/**
 * This class is the main class. This class operate DiagramDataBase class and
 * operate the rules classes that write the output SMV script file.
 * 
 * @author
 * 
 */
public class SMVCreator {

        // The number of instances in the smv code:
        static public int K;

        static public XmlParser _xmlParser;
        static public PrintStream smvErr;
        FileWriter smvScript;
        File smvErrLog;
        /**
         * Class constructor
         */
        public SMVCreator() {
                
                try {
                        _xmlParser = new XmlParser(new FileInputStream("projXml.xml"));
                        K = _xmlParser.getK();
                } catch (XmlParserException e) {
                        e.printStackTrace();
                } catch (FileNotFoundException e) {
                        e.printStackTrace();
                } catch (XPathExpressionException e) {
                        e.printStackTrace();
                }
                
        }

        /**
         * This function take the values of the variables: k, evTerm, sysTerm,
         * creation_var, pathToSave. from the given xml file. The function operate
         * DiagramDatabase class, and then operate all the rules classes. The output
         * from the rules classes is written into SMV script file.
         * 
         * @param currSystem
         *            the current ISystem
         */
        public void createSmv(ISystem currSystem){

                // default values
                K = 2;
                int evTerm = 20;
                int sysTerm = 20;
                int creation_var = 20;

                // this is the path we want to save our file in - should be received
                // from the xml file
                String pathToSave = "c:\\smvScript.smv";
                
                try {
                        sysTerm = _xmlParser.getSystemTermination();
                        evTerm = _xmlParser.getProcessTermination();
                        creation_var = _xmlParser.getEnvironmentalObjectCreation();
                        pathToSave = _xmlParser.getSavePath();
                        //saving errLog to a new file next to the SmvScript
                        java.util.Date d = new Date();
                        String errPath = pathToSave.substring(0, pathToSave.lastIndexOf('\\')+1);
                        smvErrLog = new File(errPath+"SmvErrLog"+d.getTime()+".txt");
                        if(!smvErrLog.exists()) smvErrLog.createNewFile();
                        smvErr = new PrintStream(smvErrLog);
                        System.setErr(smvErr);
                        
                } catch (Exception e) {
                        System.err.println("PROBLEM GETTING DATA FROM XML CONFIG FILE: "+ e.getMessage());
                }

                DiagramDatabase db=null;
                try {
                        db = new DiagramDatabase(currSystem, sysTerm, evTerm,
                                        creation_var);
                        db.acquireDiagramDetails(currSystem);
                } catch (SmvDBException e) {
                        System.err.println("ERROR IN DIAGRAM's DATA BASE: "+ e.getMessage());
                } catch (IOException e) {
                        System.err.println("SMVCreator: ");
                        e.printStackTrace();
                }

                // creating the rules classes
                SystemInit init = new SystemInit(db);
                ProcRule p = new ProcRule(db);
                EvObjects eo = new EvObjects(db);
                EvProcess ep = new EvProcess(db);
                EvCreate ec = new EvCreate(db);
                EvXor xorOr = new EvXor(db);
                Associations asoc = new Associations(db);

                try {
                        // deleting a previous file by that name (if such exist)
                        java.io.File file = new java.io.File(pathToSave);
                        if(file.exists()) file.delete();
                        file.createNewFile();
                        // dumping all data to file
                        smvScript = new FileWriter(pathToSave);
                        writeToFile(init.createRule());
                        writeToFile(eo.createRule());
                        writeToFile(p.createRule());
                        writeToFile(ep.createRule());
                        writeToFile(ec.createRule());
                        writeToFile(xorOr.createRule());
                        writeToFile(asoc.createRule());
                        smvScript.close();
                }
                catch (SmvCreatorException e) {
                        System.err.println("ERROR WHILE PREPARING SCRIPT: \n"+ e.getMessage());
                } catch (IOException e) {
                        System.err.println("SMVCreator: ");
                        e.printStackTrace();
                }catch(Exception e){
                        System.err.println("SMVCreator: UnKnown exception");
                        e.printStackTrace();
                }finally{
                        smvErr.flush();
                        smvErr.close();
                        System.setErr(null);
                        if(smvErrLog.length()==0)
                                smvErrLog.deleteOnExit();
                
                }
        }

        /**
         * This function Prints a string to file and flush the buffer for the 
         * next time
         * @param createRule
         * @throws IOException
         */
        private void writeToFile(String createRule) throws IOException {
                smvScript.write(createRule);
                smvScript.flush();
        }
}
